package com.xbongbong.paas.service.team;

import com.alibaba.fastjson.JSON;
import com.xbongbong.callback.help.ApiCallbackHelper;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.parent.factory.TeamDataFactory;
import com.xbongbong.parent.interfaces.TeamStrategy;
import com.xbongbong.pro.domain.entity.FormTeamSetEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormPatternEnum;
import com.xbongbong.pro.team.TeamAfterVerifyDTO;
import com.xbongbong.pro.team.TeamLinkPOJO;
import com.xbongbong.pro.team.TeamSaveByDataIdListDTO;
import com.xbongbong.pro.team.TeamUpdateMidPOJO;
import com.xbongbong.pro.team.TeamVerifyDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.PayBalanceEnum;
import com.xbongbong.saas.enums.UserTeamOperateTagEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.PayPlanEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentBalanceEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.SupplierContactEnum;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

@Slf4j
@Service
public class TeamDataBusinessHelp {

    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private TeamDataFactory teamDataFactory;
    @Resource
    private ApiCallbackHelper apiCallbackHelper;
    @Resource
    @Lazy
    private TeamDataHelp teamDataHelp;
    @Resource
    private IndexTypeModel indexTypeModel;

    /**
     * Description: 团队继承逻辑处理（没有异步线程）
     * @param teamAfterVerifyDTO
     * @return void
     * @throws
     * @author 魏荣杰
     * @date 2022/3/14 13:43
     * @since
     */
    public void inheritanceSaveWithoutThread(TeamAfterVerifyDTO teamAfterVerifyDTO) throws XbbException {
        // 已经是上游继承的，不执行其下游继承
        if (Objects.nonNull(teamAfterVerifyDTO) && !teamAfterVerifyDTO.getIsInheritance()) {
            try {
                String corpid = teamAfterVerifyDTO.getCorpid();
                Integer businessType = teamAfterVerifyDTO.getBusinessType();
                XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
                FormTeamSetEntity formTeamSetEntity = teamAfterVerifyDTO.getFormTeamSetEntity();
                if (Objects.isNull(formTeamSetEntity)) {
                    return;
                }
                Integer model = formTeamSetEntity.getModel();
                Integer publicSwitch = formTeamSetEntity.getPublicSwitch();
                //退回公海池过来的业务，若团队没有解散才会走这边，若开关关闭，则走老逻辑，老逻辑是下游不会同步团队，故直接返回
                if(teamAfterVerifyDTO.getFromBackPublic() && Objects.equals(publicSwitch,Constant.ZERO) && teamAfterVerifyDTO.getIsBack()){
                    return;
                }
                //预收款、预付款特殊逻辑(默认继承且不可编辑)
                if(Objects.equals(xbbRefTypeEnum, XbbRefTypeEnum.CUSTOMER_MANAGEMENT) || Objects.equals(xbbRefTypeEnum,XbbRefTypeEnum.SUPPLIER)){
                    batchSavePrePayBalanceTeam(teamAfterVerifyDTO);
                }
                //回款单、付款单团队更新标记 0：不涉及, 1：涉及默认继承, 2：涉及共享继承
                int sheetTeamFlag = BasicConstant.ZERO;
                //回款单、付款单特殊逻辑(经销商和订货单的此逻辑走老逻辑)
                if ( Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT, xbbRefTypeEnum)
                        || Objects.equals(XbbRefTypeEnum.CONTRACT, xbbRefTypeEnum)
                        || Objects.equals(XbbRefTypeEnum.SUPPLIER, xbbRefTypeEnum)
                        || Objects.equals(XbbRefTypeEnum.PURCHASE, xbbRefTypeEnum)) {
                    sheetTeamFlag = BasicConstant.ONE;
                }
                if (Objects.equals(model, FormPatternEnum.FORM_SHARE.getModel())) {
                    // 共享
                    List<TeamLinkPOJO> teamLinkPOJOList = JSON.parseArray(JSON.toJSONString(formTeamSetEntity.getLinkForm()), TeamLinkPOJO.class);

                    if (CollectionUtils.isNotEmpty(teamLinkPOJOList)) {
                        for (TeamLinkPOJO teamLinkPOJO : teamLinkPOJOList) {
                            Integer linkBusinessType = teamLinkPOJO.getLinkBusinessType();
                            Integer linkSaasMark = teamLinkPOJO.getLinkSaasMark();
                            String attr = "";
                            //
                            IndexTypeEnum indexTypeEnum = indexTypeModel.getByCode(corpid, linkBusinessType);
                            if (Objects.equals(linkSaasMark, SaasMarkEnum.SAAS.getCode())) {
                                switch (xbbRefTypeEnum) {
                                    case CUSTOMER_MANAGEMENT:
                                        switch (indexTypeEnum) {
                                            case IDX_SAAS_CONTACT:
                                                attr = ContractEnum.LINK_CUSTOMER.getAttr();
                                                break;
                                            case IDX_SAAS_CONTRACT:
                                                attr = ContractEnum.LINK_CUSTOMER.getAttr();
                                                break;
                                            case IDX_SAAS_REFUND:
                                                attr = RefundEnum.CUSTOMER_ID.getAttr();
                                                break;
                                            case IDX_SAAS_OPPORTUNITY:
                                                attr = SalesOpportunityEnum.CUSTOMER_NAME.getAttr();
                                                break;
                                            case IDX_SAAS_QUOTATION:
                                                attr = QuotationEnum.CUSTOMER_ID.getAttr();
                                                break;
                                            case IDX_SAAS_PAYMENT:
                                                attr = PaymentEnum.CUSTOMER.getAttr();
                                                break;
                                            case IDX_SAAS_PAYMENT_SHEET:
                                                attr = PaymentSheetEnum.CUSTOMER_ID.getAttr();
                                                sheetTeamFlag = BasicConstant.TWO;
                                                break;
                                            default:
                                                continue;
                                        }
                                        break;
                                    case CONTACT:
                                        break;
                                    case SALES_OPPORTUNITY:
                                        switch (indexTypeEnum) {
                                            case IDX_SAAS_CONTRACT:
                                                attr = ContractEnum.LINK_OPPORTUNITY.getAttr();
                                                break;
                                            case IDX_SAAS_QUOTATION:
                                                attr = QuotationEnum.OPPORTUNITY_ID.getAttr();
                                                break;
                                            default:
                                        }
                                        break;
                                    case QUOTATION:
                                        break;
                                    case CONTRACT:
                                        switch (indexTypeEnum) {
                                            case IDX_SAAS_PAYMENT:
                                                attr = PaymentEnum.CONTRACT.getAttr();
                                                break;
                                            case IDX_SAAS_REFUND:
                                                attr = RefundEnum.CONTRACT_ID.getAttr();
                                                break;
                                            case IDX_SAAS_PAYMENT_SHEET:
                                                attr = PaymentSheetEnum.CONTRACT.getAttr();
                                                sheetTeamFlag = BasicConstant.TWO;
                                                break;
                                            default:
                                        }
                                        break;
                                    case PAYMENT_MANAGEMENT:
                                        break;
                                    case PAY_PLAN:
                                        switch (indexTypeEnum) {
                                            case IDX_SAAS_PAYPLAN_SHEET:
                                                //attr = PaySheetEnum.PAY_PLAN.getAttr();
                                                sheetTeamFlag = BasicConstant.TWO;
                                                break;
                                            default:
                                        }
                                        break;
                                    case PAYMENT:
                                        break;
                                    case PAYMENT_SHEET:
                                        break;
                                    case SUPPLIER:
                                        switch (indexTypeEnum) {
                                            case IDX_SAAS_SUPPLIER_CONTACT:
                                                attr = SupplierContactEnum.SUPPLIER_ID.getAttr();
                                                break;
                                            case IDX_SAAS_PAY_PLAN:
                                                attr = PayPlanEnum.LINK_SUPPLIER.getAttr();
                                                break;
                                            case IDX_SAAS_PAYPLAN_SHEET:
                                                attr = PaySheetEnum.LINK_SUPPLIER.getAttr();
                                                sheetTeamFlag = BasicConstant.TWO;
                                                break;
                                            case IDX_SAAS_PURCHASE:
                                                attr = PurchaseEnum.SUPPLIER_ID.getAttr();
                                                break;
                                            default:
                                        }
                                        break;
                                    case PURCHASE:
                                        switch (indexTypeEnum) {
                                            case IDX_SAAS_PAY_PLAN:
                                                attr = PayPlanEnum.LINK_PURCHASE.getAttr();
                                                break;
                                            case IDX_SAAS_PAYPLAN_SHEET:
                                                attr = PaySheetEnum.LINK_PURCHASE.getAttr();
                                                sheetTeamFlag = BasicConstant.TWO;
                                                break;
                                            default:
                                        }
                                        break;
                                    case PRODUCTION_ORDER:
                                        break;
                                    case MARKET_ACTIVITY:
                                        switch (indexTypeEnum) {
                                            case IDX_SAAS_CLUE:
                                                attr = ClueEnum.MARKET_ACTIVITY_ID.getAttr();
                                                break;
                                            default:
                                        }
                                        break;
                                    case CLUE:
                                        switch (indexTypeEnum) {
                                            case IDX_SAAS_CUSTOMER:
                                                attr = CustomerManagementEnum.CLUE_ID.getAttr();
                                                break;
                                            default:
                                        }
                                        break;
                                    default:
                                }
                            }
                            List<PaasFormEntityExt> paasFormEntityList = formatPassFormEntity(teamLinkPOJO, corpid);
                            for (PaasFormEntity paasFormEntity : paasFormEntityList) {
                                TeamSaveByDataIdListDTO teamSaveByDataIdListDTO = new TeamSaveByDataIdListDTO();
                                BeanUtil.copyProperties(teamAfterVerifyDTO,teamSaveByDataIdListDTO);
                                teamSaveByDataIdListDTO.setSubBusinessType(teamLinkPOJO.getLinkBusinessType());
                                teamSaveByDataIdListDTO.setAttr(attr);
                                teamSaveByDataIdListDTO.setIndexTypeEnum(indexTypeEnum);
                                teamSaveByDataIdListDTO.setPaasFormEntity(paasFormEntity);
                                teamSaveByDataIdList(teamSaveByDataIdListDTO);
                            }
                        }
                    }
                } else {
                    // 隔离不做继承操作

                }
                //回款单、付款单团队特殊逻辑
                if(Objects.equals(sheetTeamFlag,BasicConstant.ONE) || Objects.equals(sheetTeamFlag, BasicConstant.TWO)){
                    updateSheetTeam(teamAfterVerifyDTO,sheetTeamFlag);
                }
            } catch (Exception e) {
                log.error("team orginial error", e);
                log.error("team share or isolation execute fail, corpid: {}, dataIds: {}, operateTag: {}, formId: {}, businessType: {}, isInheritance: {}, isBack: {}, batchTag: {}", teamAfterVerifyDTO.getCorpid(), JSON.toJSONString(teamAfterVerifyDTO.getDataId()), teamAfterVerifyDTO.getOperateTag(), teamAfterVerifyDTO.getFormId(),teamAfterVerifyDTO.getBusinessType(), teamAfterVerifyDTO.getIsInheritance(), teamAfterVerifyDTO.getIsBack(), teamAfterVerifyDTO.getBatchTag());

            }
        }
    }

    /**
     * Description: 团队继承逻辑处理（有异步线程）
     * @param teamAfterVerifyDTO
     * @return void
     * @throws
     * @author 魏荣杰
     * @date 2022/3/14 13:43
     * @since
     */
    @Async(value = "teamThreadPool")
    public void inheritanceSave(TeamAfterVerifyDTO teamAfterVerifyDTO) throws XbbException {
       inheritanceSaveWithoutThread(teamAfterVerifyDTO);
    }

    /**
     *
     * @Description: 批量保存预收/付款团队
     * @param teamAfterVerifyDTO
     * @return: void
     * @Author: shen.yang
     * @Date: 2022/2/17  15:24
     */
    private void batchSavePrePayBalanceTeam(TeamAfterVerifyDTO teamAfterVerifyDTO) throws XbbException {
        String corpid = teamAfterVerifyDTO.getCorpid();
        Integer businessType = teamAfterVerifyDTO.getBusinessType();
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        IndexTypeEnum indexTypeEnum = null;
        String attr = "";
        PaasFormEntityExt paasFormEntity = null;

        if(Objects.equals(xbbRefTypeEnum,XbbRefTypeEnum.CUSTOMER_MANAGEMENT)){
            //客户写死关联预收款团队
            paasFormEntity = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode(), corpid,teamAfterVerifyDTO.getDistributorMark(),null);
            attr = PaymentBalanceEnum.CUSTOMER_ID.getAttr();
            indexTypeEnum = IndexTypeEnum.getByCode(XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode());
        } else if(Objects.equals(xbbRefTypeEnum,XbbRefTypeEnum.SUPPLIER)){
            //供应商写死关联预付款团队
            paasFormEntity = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.PREPAY_BALANCE.getCode(), corpid,teamAfterVerifyDTO.getDistributorMark(),null);
            attr = PayBalanceEnum.SUPPLIER_ID.getAttr();
            indexTypeEnum = IndexTypeEnum.getByCode(XbbRefTypeEnum.PREPAY_BALANCE.getCode());
        }
        if(Objects.isNull(indexTypeEnum) || Objects.isNull(paasFormEntity) || StringUtil.isEmpty(attr)){
            return;
        }
        TeamSaveByDataIdListDTO teamSaveByDataIdListDTO = new TeamSaveByDataIdListDTO();
        BeanUtil.copyProperties(teamAfterVerifyDTO,teamSaveByDataIdListDTO);
        teamSaveByDataIdListDTO.setAttr(attr);
        teamSaveByDataIdListDTO.setIndexTypeEnum(indexTypeEnum);
        teamSaveByDataIdListDTO.setPaasFormEntity(paasFormEntity);
        teamSaveByDataIdList(teamSaveByDataIdListDTO);
    }

    /**
     *
     * @Description: linkForm保存只关联到menu级别，进一步关联到菜单下所有启用的表单
     * @param teamLinkPOJO
     * @param corpid
     * @return: java.util.List<com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt>
     * @Author: shen.yang
     * @Date: 2022/2/23  14:26
     */
    private  List<PaasFormEntityExt> formatPassFormEntity(TeamLinkPOJO teamLinkPOJO, String corpid){
        Integer linkSaasMark = teamLinkPOJO.getLinkSaasMark();
        Integer linkBusinessType = teamLinkPOJO.getLinkBusinessType();
        Integer linkDistributorMark = teamLinkPOJO.getDistributorMark();

        Map<String,Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.CORPID,corpid);
        params.put(ParameterConstant.ENABLE, Constant.ONE);
        params.put("saasMark",linkSaasMark);
        params.put("businessType",linkBusinessType);
        params.put("distributorMark",linkDistributorMark);
        List<PaasFormEntityExt> forms = paasFormModel.findEntitys(params);

        //过滤未启用表单
        filterUnenableAppAndForm(corpid,forms);
        return forms;
    }

    /**
     *
     * @Description: 过滤未开启的表单
     * @param corpid
     * @param paasFormEntityExtList 表单list
     * @return: void
     * @Author: shen.yang
     * @Date: 2022/2/23  14:25
     */
    private void filterUnenableAppAndForm(String corpid, List<PaasFormEntityExt> paasFormEntityExtList) {
        Set<Long> appIds = new HashSet<>();
        Set<Long> menuIds = new HashSet<>();
        paasFormEntityExtList.forEach(v -> {
            appIds.add(v.getAppId());
            menuIds.add(v.getMenuId());
        });

        Map<String, Object> params = new HashMap<>();
        params.put(ParameterConstant.CORPID, corpid);
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        params.put(ParameterConstant.ENABLE, 1);
        params.put(ParameterConstant.ID_IN, appIds);
        List<PaasAppEntity> paasAppEntities = paasAppModel.findEntitys(params);

        Map<Long, PaasAppEntity> appMap = new HashMap<>();
        paasAppEntities.forEach(v -> appMap.put(v.getId(), v));

        params.put(ParameterConstant.ID_IN, menuIds);
        List<PaasMenuEntity> menuModelEntitys = paasMenuModel.findEntitys(params);

        Map<Long, PaasMenuEntity> menuMap = new HashMap<>();
        menuModelEntitys.forEach(v -> menuMap.put(v.getId(), v));

        List<Long> formIds = new ArrayList<>();
        List<Long> workOrderFormIds = new ArrayList<>();
        for (PaasFormEntityExt paasFormEntityExt : paasFormEntityExtList) {
            if (appMap.isEmpty() || menuMap.isEmpty()) {
                continue;
            }

            if (appMap.containsKey(paasFormEntityExt.getAppId()) && menuMap.containsKey(paasFormEntityExt.getMenuId())) {
                if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), paasFormEntityExt.getBusinessType())) {
                    workOrderFormIds.add(paasFormEntityExt.getId());
                } else {
                    formIds.add(paasFormEntityExt.getId());
                }
            }
        }

        Map<Long, PaasFormEntityExt> formMap = new HashMap<>();
        Map<Long, WorkOrderFormEntity> workOrderFormMap = new HashMap<>();
        if (CollectionsUtil.isNotEmpty(formIds)) {
            params.clear();
            params.put(ParameterConstant.CORPID, corpid);
            params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            params.put(ParameterConstant.ID_IN, formIds);
            params.put(ParameterConstant.ENABLE, 1);
            List<PaasFormEntityExt> paasFormEntityExts = paasFormModel.findEntitys(params);
            if (CollectionsUtil.isNotEmpty(paasFormEntityExts)) {
                paasFormEntityExts.forEach(v -> formMap.put(v.getId(), v));
            }
        }

        if (CollectionsUtil.isNotEmpty(workOrderFormIds)) {
            List<WorkOrderFormEntity> workOrderFormEntities = workOrderFormModel.findEntitys(params);
            if (CollectionsUtil.isNotEmpty(workOrderFormEntities)) {
                workOrderFormEntities.forEach(v -> workOrderFormMap.put(v.getId(), v));
            }
        }

        Iterator<PaasFormEntityExt> iterator = paasFormEntityExtList.iterator();
        while (iterator.hasNext()) {
            PaasFormEntityExt next = iterator.next();
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), next.getBusinessType())) {
                WorkOrderFormEntity workOrderFormEntity = workOrderFormMap.get(next.getId());
                if (Objects.isNull(workOrderFormEntity)) {
                    iterator.remove();
                    continue;
                }
                next.setName(workOrderFormEntity.getName());
            } else {
                PaasFormEntityExt paasFormEntityExt = formMap.get(next.getId());
                if (Objects.isNull(paasFormEntityExt)) {
                    iterator.remove();
                    continue;
                }
                next.setName(paasFormEntityExt.getName());
            }
        }
    }


    /**
     *
     * @Description: 批量保存团队成员
     * @param teamSaveByDataIdListDTO
     * @return: void
     * @Author: shen.yang
     * @Date: 2022/2/23  14:27
     */
    private void teamSaveByDataIdList(TeamSaveByDataIdListDTO teamSaveByDataIdListDTO) throws XbbException {
        List<Long> dataIdIn = teamSaveByDataIdListDTO.getDataId();
        String attr = teamSaveByDataIdListDTO.getAttr();
        IndexTypeEnum indexTypeEnum = teamSaveByDataIdListDTO.getIndexTypeEnum();
        PaasFormEntity paasFormEntity = teamSaveByDataIdListDTO.getPaasFormEntity();
        String corpid = teamSaveByDataIdListDTO.getCorpid();
        Long appId = paasFormEntity.getAppId();
        Long menuId = paasFormEntity.getMenuId();
        Long formId = paasFormEntity.getId();
        List<String> fieldList = Collections.singletonList(FieldTypeEnum.DATAID.getAlias());
        BoolQueryBuilder boolQueryBuilder;
        //回款单付款单业务需要特殊处理，见updateSheetTeam()方法，此处不用处理
        if(Objects.equals(indexTypeEnum,IndexTypeEnum.IDX_SAAS_PAYMENT_SHEET) || Objects.equals(indexTypeEnum,IndexTypeEnum.IDX_SAAS_PAYPLAN_SHEET)){
            return;
        }
        Integer operateTag = teamSaveByDataIdListDTO.getOperateTag();
        for (Long dataId : dataIdIn) {
            try {
                boolQueryBuilder = boolQuery();
                if (!Objects.equals(IndexTypeEnum.IDX_PAYMENT_BALANCE, indexTypeEnum) && !Objects.equals(IndexTypeEnum.IDX_PAY_BALANCE, indexTypeEnum)) {
                    boolQueryBuilder.filter(termsQuery(FieldTypeEnum.FLOW_STATUS.getAlias(), Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
                }
                boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
                boolQueryBuilder.filter(termQuery(ParameterConstant.DEL, DelEnum.NORMAL.getDel()));
                if (attr.contains("subForm")) {
                    // 子表单内关联字段处理
                    String[] split = attr.split("\\.");
                    indexTypeEnum = IndexTypeEnum.IDX_SUB_FORM_DATA;
                    boolQueryBuilder.filter(termQuery("data." + split[1] + ".keyword", dataId));
                    boolQueryBuilder.filter(termQuery("attr", split[0]));
                    boolQueryBuilder.filter(termQuery(ParameterConstant.FORMID, formId));
                } else {
                    //预收款、预付款的表结构不同，需单独判断
                    if(Objects.equals(indexTypeEnum,IndexTypeEnum.IDX_PAYMENT_BALANCE) || Objects.equals(indexTypeEnum,IndexTypeEnum.IDX_PAY_BALANCE)){
                        boolQueryBuilder.filter(termQuery(attr, dataId));
                    }else{
                        boolQueryBuilder.filter(termQuery("data." + attr + ".keyword", dataId));
                    }
                    boolQueryBuilder.filter(termQuery(ParameterConstant.FORMID, formId));
                    boolQueryBuilder.filter(termQuery(ParameterConstant.APPID, appId));
                    boolQueryBuilder.filter(termQuery(ParameterConstant.MENUID, menuId));
                }

                //已经在公海池里的客户和线索，不会因上游业务的修改而变动团队
                if(Objects.equals(indexTypeEnum,IndexTypeEnum.IDX_SAAS_CLUE)){
                    boolQueryBuilder.filter(termQuery("data." + ClueEnum.IS_PUBLIC.getAttr(), Constant.ZERO));
                }else if(Objects.equals(indexTypeEnum,IndexTypeEnum.IDX_SAAS_CUSTOMER) || Objects.equals(IndexTypeEnum.IDX_SAAS_CUSTOMER_SPECIAL, indexTypeEnum)) {
                    boolQueryBuilder.filter(termQuery("data." + CustomerManagementEnum.IS_PUBLIC.getAttr(), Constant.ZERO));
                }
                if((Objects.equals(indexTypeEnum,IndexTypeEnum.IDX_PAYMENT_BALANCE) || Objects.equals(indexTypeEnum,IndexTypeEnum.IDX_PAY_BALANCE))){
                    fieldList = Collections.singletonList(FieldTypeEnum.ID.getAlias());
                }
                List<PaasFormDataEntityExt> paasFormDataList = esHelper.findByScroll(indexTypeEnum, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList);


                List<Long> formDataIdIn = (Objects.equals(indexTypeEnum,IndexTypeEnum.IDX_PAYMENT_BALANCE) || Objects.equals(indexTypeEnum,IndexTypeEnum.IDX_PAY_BALANCE)) ?
                        paasFormDataList.stream().map(PaasFormDataEntity::getId).collect(Collectors.toList()) : paasFormDataList.stream().map(PaasFormDataEntity::getDataId).collect(Collectors.toList());
                if (formDataIdIn.isEmpty()) {
                    continue;
                }

                TeamStrategy linkTeamStrategy = teamDataFactory.getStrategy(paasFormEntity.getBusinessType(), paasFormEntity.getDistributorMark(), teamSaveByDataIdListDTO.getSaasMark());
                TeamVerifyDTO verifyDTO = new TeamVerifyDTO();
                //下游团队的处理才走这个方法， 走tab页的校验，增量校验
                verifyDTO.setFromDetail(true);
                verifyDTO.setCorpid(corpid);
                verifyDTO.setFormId(formId);
                verifyDTO.setSaasMark(paasFormEntity.getSaasMark());
                verifyDTO.setBusinessType(paasFormEntity.getBusinessType());
                verifyDTO.setSubBusinessType(teamSaveByDataIdListDTO.getSubBusinessType());
                verifyDTO.setDistributorMark(paasFormEntity.getDistributorMark());
                verifyDTO.setDataId(formDataIdIn);
                verifyDTO.setOperateTag(operateTag);
                // 继承的不校验，可以不需要这个参数
//                   verifyDTO.setCreatorId();
                Set<String> updateToMainUserList = teamSaveByDataIdListDTO.getUpdateToMainUserMap().get(String.valueOf(dataId));
                Set<String> newAddMainUserList = teamSaveByDataIdListDTO.getAddMainUserMap().get(String.valueOf(dataId));
                Set<String> newDelCoUserList = teamSaveByDataIdListDTO.getDelCoUserMap().get(String.valueOf(dataId));
                if (Objects.equals(UserTeamOperateTagEnum.HANDOVER.getOperateTag(), operateTag) && CollectionsUtil.isNotEmpty(updateToMainUserList)) {
                    //移交这边有个特殊逻辑，就是如果上游业务是协同人转负责人，那么下游业务其实是addMainUserMap和有delCouser值
                    verifyDTO.setNewAddMainUserList(updateToMainUserList);
                    verifyDTO.setNewDelCoUserList(updateToMainUserList);
                }else {
                    verifyDTO.setNewAddMainUserList( Objects.isNull(newAddMainUserList) ? new HashSet<>() : newAddMainUserList );
                    verifyDTO.setNewDelCoUserList(Objects.isNull(newDelCoUserList) ? new HashSet<>() : newDelCoUserList);
                }
                Set<String> newDelMainUserList = teamSaveByDataIdListDTO.getDelMainUserMap().get(String.valueOf(dataId));
                verifyDTO.setNewDelMainUserList(Objects.isNull(newDelMainUserList) ? new HashSet<>() : newDelMainUserList);
                Set<String> newAddCoUserList = teamSaveByDataIdListDTO.getAddCoUserMap().get(String.valueOf(dataId));
                verifyDTO.setNewAddCoUserList(Objects.isNull(newAddCoUserList) ? new HashSet<>() : newAddCoUserList);
                verifyDTO.setFromBackPublic(teamSaveByDataIdListDTO.getFromBackPublic());
                verifyDTO.setIsInheritance(true);
                //从公海池等场景过来的，不需要做校验，也没有loginuser参数
                if(!verifyDTO.getFromBackPublic()){
                    verifyDTO.setUserId(teamSaveByDataIdListDTO.getLoginUser().getUserId());
                    verifyDTO.setLoginUser(teamSaveByDataIdListDTO.getLoginUser());
                }

                TeamAfterVerifyDTO afterVerifyDTO = linkTeamStrategy.verify(verifyDTO);
                afterVerifyDTO = linkTeamStrategy.specialVerify(afterVerifyDTO);

                linkTeamStrategy.save(afterVerifyDTO);
                // 后续默认业务处理
                //也是只有tab页才会走
                if (Objects.equals(teamSaveByDataIdListDTO.getFromDetail(), true)) {
                    linkTeamStrategy.afterSave(afterVerifyDTO);
                }
                // api回调
                apiCallBack(verifyDTO.getDataId(), paasFormEntity.getBusinessType(), corpid);
            } catch (Exception e) {
                log.error("团队成员下游业务数据继承逻辑出错:{}, corpid : {}, 操作标识operateTag:{}, 父businessType:{}, 子businessType:{}, originalDataId:{}", e, corpid, operateTag,
                        teamSaveByDataIdListDTO.getBusinessType(), teamSaveByDataIdListDTO.getSubBusinessType(), dataId);
            }

        }
    }

    /**
     *
     * @Description: 付款单、回款单特殊逻辑
     * @param
     * @return: void
     * @Author: shen.yang
     * @Date: 2022/2/18  14:04
     */
    private void updateSheetTeam(TeamAfterVerifyDTO teamAfterVerifyDTO, Integer sheetTeamFlag) throws XbbException {
        Integer businessType = teamAfterVerifyDTO.getBusinessType();
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        String corpid = teamAfterVerifyDTO.getCorpid();
        List<Long> dataIdIn = teamAfterVerifyDTO.getDataId();
        //查出所有的回款单/付款单数据
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(ParameterConstant.DEL, DelEnum.NORMAL.getDel()));
        List<String> fieldList = new ArrayList<>();
        IndexTypeEnum indexTypeEnum = null;
        Integer distributorMark = teamAfterVerifyDTO.getDistributorMark();
        XbbRefTypeEnum linkXbbRefTypeEnum = null;
        for (Long dataId : dataIdIn) {

            if (Objects.equals(sheetTeamFlag, BasicConstant.TWO)) {
                //继承
                switch (xbbRefTypeEnum) {
                    case CUSTOMER_MANAGEMENT:
                        //若客户关联了回款单，则所有回款单类型均继承客户
                        boolQueryBuilder.filter(termQuery("data." + PaymentSheetEnum.CUSTOMER_ID.getAttr() + ".keyword", dataId.toString()));
                        fieldList.add(PaymentSheetEnum.getAttrConnectData(PaymentSheetEnum.CUSTOMER_ID));
                        indexTypeEnum = IndexTypeEnum.getByCode(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
                        linkXbbRefTypeEnum = XbbRefTypeEnum.PAYMENT_SHEET;
                        break;
                    case CONTRACT://若合同关联回款单，则已核销、预收款核销、红冲已核销、红冲预收款核销、红冲预收款核销(退到余额)、坏账类型的回款单继承合同团队
                        boolQueryBuilder.filter(matchPhraseQuery("data." + PaymentSheetEnum.CONTRACT.getAttr(), dataId.toString()));
                        fieldList.add(PaymentSheetEnum.getAttrConnectData(PaymentSheetEnum.CONTRACT));
                        boolQueryBuilder.filter(termsQuery(PaymentSheetEnum.getEsAttr4Keyword(PaymentSheetEnum.PAYMENT_SHEET_TYPE), SheetTypeEnum.belongOther(XbbRefTypeEnum.PAYMENT_SHEET)));
                        indexTypeEnum = IndexTypeEnum.getByCode(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
                        linkXbbRefTypeEnum = XbbRefTypeEnum.PAYMENT_SHEET;
                        break;
                    case SUPPLIER://若供应商关联付款单，则所有付款单类型均继承客户
                        boolQueryBuilder.filter(termQuery("data." + PaySheetEnum.LINK_SUPPLIER.getAttr() + ".keyword", dataId.toString()));
                        fieldList.add(PaySheetEnum.getAttrConnectData(PaySheetEnum.LINK_SUPPLIER));
                        indexTypeEnum = IndexTypeEnum.getByCode(XbbRefTypeEnum.PAY_SHEET.getCode());
                        linkXbbRefTypeEnum = XbbRefTypeEnum.PAY_SHEET;
                        break;
                    case PURCHASE://若采购合同关联付款单，则已核销、预收款核销、红冲已核销、红冲预收款核销、坏账类型的付款单继承采购合同团队
                        boolQueryBuilder.filter(matchPhraseQuery("data." + PaySheetEnum.LINK_PURCHASE.getAttr(), dataId.toString()));
                        fieldList.add(PaySheetEnum.getAttrConnectData(PaySheetEnum.LINK_PURCHASE));
                        boolQueryBuilder.filter(termsQuery(PaySheetEnum.getEsAttr4Keyword(PaySheetEnum.PAY_SHEET_TYPE), SheetTypeEnum.belongOther(XbbRefTypeEnum.PAY_SHEET)));
                        indexTypeEnum = IndexTypeEnum.getByCode(XbbRefTypeEnum.PAY_SHEET.getCode());
                        linkXbbRefTypeEnum = XbbRefTypeEnum.PAY_SHEET;
                        break;
                    case PAY_PLAN://若付款计划关联付款单，则已核销、预收款核销、红冲已核销、红冲预收款核销、坏账类型的回款单继承合同团队
                        boolQueryBuilder.filter(matchPhraseQuery("data." + PaySheetEnum.PAY_PLAN.getAttr(), dataId.toString()));
                        fieldList.add(PaySheetEnum.getAttrConnectData(PaySheetEnum.PAY_PLAN));
                        boolQueryBuilder.filter(termsQuery(PaySheetEnum.getEsAttr4Keyword(PaySheetEnum.PAY_SHEET_TYPE), SheetTypeEnum.belongOther(XbbRefTypeEnum.PAY_SHEET)));
                        indexTypeEnum = IndexTypeEnum.getByCode(XbbRefTypeEnum.PAY_SHEET.getCode());
                        linkXbbRefTypeEnum = XbbRefTypeEnum.PAY_SHEET;
                        break;
                    default:
                         break;
                }
            } else if (Objects.equals(sheetTeamFlag, BasicConstant.ONE)) {
                //不走继承
                //写死继承的回款、付款单逻辑
                switch (xbbRefTypeEnum) {
                    case CUSTOMER_MANAGEMENT:
                        //客户和经销商团队写死关联预收款、红冲预收款余额类型的回款单
                        boolQueryBuilder.filter(termQuery("data." + PaymentSheetEnum.CUSTOMER_ID.getAttr() + ".keyword", dataId.toString()));
                        fieldList.add(PaymentSheetEnum.getAttrConnectData(PaymentSheetEnum.CUSTOMER_ID));
                        //如果不是来自继承，则只同步默认继承的回款单类型即可
                        boolQueryBuilder.filter(termsQuery(PaymentSheetEnum.getEsAttr4Keyword(PaymentSheetEnum.PAYMENT_SHEET_TYPE), SheetTypeEnum.belongPrepay(XbbRefTypeEnum.PAYMENT_SHEET)));
                        indexTypeEnum = IndexTypeEnum.getByCode(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
                        linkXbbRefTypeEnum = XbbRefTypeEnum.PAYMENT_SHEET;
                        break;
                    case CONTRACT: if(Objects.equals(teamAfterVerifyDTO.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR)){
                            //经销商的订货单团队写死关联 已核销、预收款核销、红冲已核销、红冲预收款核销、红冲预收款核销(退到余额)、坏账 类型的回款单
                        boolQueryBuilder.filter(matchPhraseQuery("data." + PaymentSheetEnum.CONTRACT.getAttr(), dataId.toString()));
                        fieldList.add(PaymentSheetEnum.getAttrConnectData(PaymentSheetEnum.CONTRACT));
                        boolQueryBuilder.filter(termsQuery(PaymentSheetEnum.getEsAttr4Keyword(PaymentSheetEnum.PAYMENT_SHEET_TYPE), SheetTypeEnum.belongOther(XbbRefTypeEnum.PAYMENT_SHEET)));
                        indexTypeEnum = IndexTypeEnum.getByCode(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
                        linkXbbRefTypeEnum = XbbRefTypeEnum.PAYMENT_SHEET;
                        }
                        break;
                    case SUPPLIER://供应商团队写死关联预付款、红冲预付款余额类型的付款单
                        boolQueryBuilder.filter(termQuery("data." + PaySheetEnum.LINK_SUPPLIER.getAttr() + ".keyword", dataId.toString()));
                        fieldList.add(PaySheetEnum.getAttrConnectData(PaySheetEnum.LINK_SUPPLIER));
                        boolQueryBuilder.filter(termsQuery(PaySheetEnum.getEsAttr4Keyword(PaySheetEnum.PAY_SHEET_TYPE), SheetTypeEnum.belongPrepay(XbbRefTypeEnum.PAY_SHEET)));
                        indexTypeEnum = IndexTypeEnum.getByCode(XbbRefTypeEnum.PAY_SHEET.getCode());
                        linkXbbRefTypeEnum = XbbRefTypeEnum.PAY_SHEET;
                        break;
                    case PURCHASE:
                        break;
                    default:
                        break;
                }
            }
            if (Objects.isNull(indexTypeEnum)) {
                return;
            }
            //查出该客户/供应商(付款计划)关联的回款单/付款单
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            fieldList.add(FieldTypeEnum.ID.getAlias());
            fieldList.add(FieldTypeEnum.FORM_ID.getAlias());
            boolQueryBuilder.filter(termsQuery(FieldTypeEnum.FLOW_STATUS.getAlias(), Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
            List<PaasFormDataEntityExt> paasFormDataList = esHelper.findByScroll(indexTypeEnum, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList);
            if(CollectionsUtil.isEmpty(paasFormDataList)){
                return;
            }
            Long formId = paasFormDataList.get(0).getFormId();
            List<Long> sheetIdIn = paasFormDataList.stream().map(PaasFormDataEntityExt::getDataId).collect(Collectors.toList());
            TeamUpdateMidPOJO teamUpdateMidPOJO = new TeamUpdateMidPOJO(corpid, sheetIdIn, formId, teamAfterVerifyDTO.getSaasMark(), linkXbbRefTypeEnum.getCode(), distributorMark,
                    teamAfterVerifyDTO.getAddMainUserMap().get(String.valueOf(dataId)), teamAfterVerifyDTO.getDelMainUserMap().get(String.valueOf(dataId)),
                    teamAfterVerifyDTO.getAddCoUserMap().get(String.valueOf(dataId)), teamAfterVerifyDTO.getDelCoUserMap().get(String.valueOf(dataId)), teamAfterVerifyDTO.getLoginUser(), false, true);
            teamUpdateMidPOJO.setOprateTag(teamAfterVerifyDTO.getOperateTag());
            TeamAfterVerifyDTO sheetTeamAfterVerifyDTO = teamDataHelp.basicVerify(teamUpdateMidPOJO, null);
            teamDataHelp.batchUpdateTeam(sheetTeamAfterVerifyDTO);
        }

    }

    /**
     * Description: api接口回调
     * @param dataIds
     * @param businessType
     * @param corpid
     * @return void
     * @throws
     * @author 魏荣杰
     * @date 2022/2/24 19:30
     * @since
     */
    public void apiCallBack(List<Long> dataIds, Integer businessType, String corpid) {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        if (Objects.equals(businessType, 100)) {
            xbbRefTypeEnum = XbbRefTypeEnum.CUSTOMER;
        }
        switch (xbbRefTypeEnum) {
            case CUSTOMER_MANAGEMENT:
            case CUSTOMER:
            case SALES_OPPORTUNITY:
            case CONTRACT:
            case PAYMENT:
            case PAYMENT_SHEET:
            case PRODUCT:
            case CLUE:
            case CUSTOMER_COMMUNICATE:
            case WAREHOUSE:
            case CONTACT:
            case PURCHASE:
            case SUPPLIER:
            case WORK_ORDER:
            case SYSTEM:
                apiCallbackHelper.callbackBatch4Special(corpid, SaasMarkEnum.SAAS, dataIds, OperateTypeEnum.EDIT, xbbRefTypeEnum);
            default:
                break;
        }
    }

}
